package com.yxt.qmgf.number.service;

import com.yxt.qmgf.number.vo.GameConfig;
import com.yxt.qmgf.number.vo.GameState;
import com.yxt.qmgf.number.vo.ScoreRecord;
import com.yxt.qmgf.userinfo.vo.UserInfoVO;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class sudokuService {
    private static final String SCORE_FILE = "sudoku_scores.dat";
    private GameState currentGame;

    // 生成新游戏
    public GameState generateNewGame(GameConfig config) {
        int[][] solvedBoard = generateSolvedBoard();
        int[][] playableBoard = createPlayableBoard(solvedBoard, config.getDifficulty());
        // 传入难度参数
        currentGame = new GameState(playableBoard, solvedBoard, config.getDifficulty());
        return currentGame;
    }

    // 生成已解决的数独板
    private int[][] generateSolvedBoard() {
        int[][] board = new int[9][9];
        fillDiagonalBoxes(board);
        fillRemaining(0, 3, board);
        return board;
    }

    // 填充对角线上的3x3宫格
    private void fillDiagonalBoxes(int[][] board) {
        for (int i = 0; i < 9; i += 3) {
            fillBox(i, i, board);
        }
    }

    // 填充一个3x3宫格
    private void fillBox(int row, int col, int[][] board) {
        Random rand = new Random();
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                int num;
                do {
                    num = rand.nextInt(9) + 1;
                } while (!isValidInBox(row, col, num, board));
                board[row + i][col + j] = num;
            }
        }
    }

    // 递归填充剩余格子
    private boolean fillRemaining(int i, int j, int[][] board) {
        if (j >= 9 && i < 8) {
            i++;
            j = 0;
        }
        if (i >= 9 && j >= 9) {
            return true;
        }

        if (i < 3) {
            if (j < 3) j = 3;
        } else if (i < 6) {
            if (j == (i / 3) * 3) j += 3;
        } else {
            if (j == 6) {
                i++;
                j = 0;
                if (i >= 9) return true;
            }
        }

        for (int num = 1; num <= 9; num++) {
            if (isValid(i, j, num, board)) {
                board[i][j] = num;
                if (fillRemaining(i, j + 1, board)) {
                    return true;
                }
                board[i][j] = 0;
            }
        }
        return false;
    }

    // 创建可玩的数独板(挖空)
    private int[][] createPlayableBoard(int[][] solvedBoard, int difficulty) {
        int[][] playableBoard = new int[9][9];
        for (int i = 0; i < 9; i++) {
            System.arraycopy(solvedBoard[i], 0, playableBoard[i], 0, 9);
        }

        int cellsToRemove = 0;
        switch (difficulty) {
            case 1: cellsToRemove = 40; break; // 简单
            case 2: cellsToRemove = 50; break; // 中等
            case 3: cellsToRemove = 60; break; // 困难
        }

        Random rand = new Random();
        while (cellsToRemove > 0) {
            int row = rand.nextInt(9);
            int col = rand.nextInt(9);

            if (playableBoard[row][col] != 0) {
                playableBoard[row][col] = 0;
                cellsToRemove--;
            }
        }

        return playableBoard;
    }

    // 验证数字在当前位置是否有效
    public boolean isValid(int row, int col, int num, int[][] board) {
        return !usedInRow(row, num, board) &&
                !usedInCol(col, num, board) &&
                !usedInBox(row - row % 3, col - col % 3, num, board);
    }

    private boolean usedInRow(int row, int num, int[][] board) {
        for (int col = 0; col < 9; col++) {
            if (board[row][col] == num) {
                return true;
            }
        }
        return false;
    }

    private boolean usedInCol(int col, int num, int[][] board) {
        for (int row = 0; row < 9; row++) {
            if (board[row][col] == num) {
                return true;
            }
        }
        return false;
    }

    private boolean usedInBox(int boxStartRow, int boxStartCol, int num, int[][] board) {
        for (int row = 0; row < 3; row++) {
            for (int col = 0; col < 3; col++) {
                if (board[row + boxStartRow][col + boxStartCol] == num) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isValidInBox(int row, int col, int num, int[][] board) {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[row + i][col + j] == num) {
                    return false;
                }
            }
        }
        return true;
    }

    // 检查游戏是否完成
    public boolean isGameComplete(int[][] board) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] == 0 || !isValid(i, j, board[i][j], board)) {
                    return false;
                }
            }
        }
        return true;
    }

    // 保存分数记录
    public void saveScore(UserInfoVO user, int difficulty, int time, int mistakes) {
        List<ScoreRecord> records = loadScores();
        ScoreRecord newRecord = new ScoreRecord(
                user.getUsername(),
                user.getName(),
                difficulty,
                time,
                mistakes,
                System.currentTimeMillis()
        );
        records.add(newRecord);
        saveScoresToFile(records);
    }

    // 加载分数记录
    @SuppressWarnings("unchecked")
    public List<ScoreRecord> loadScores() {
        File file = new File(SCORE_FILE);
        if (!file.exists()) {
            return new ArrayList<>();
        }

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(SCORE_FILE))) {
            return (List<ScoreRecord>) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    // 保存分数到文件
    private void saveScoresToFile(List<ScoreRecord> records) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(SCORE_FILE))) {
            oos.writeObject(records);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 获取用户分数记录
    public List<ScoreRecord> getUserScores(String userId) {
        List<ScoreRecord> allRecords = loadScores();
        List<ScoreRecord> userRecords = new ArrayList<>();

        for (ScoreRecord record : allRecords) {
            if (record.getUsername().equals(userId)) {
                userRecords.add(record);
            }
        }

        Collections.sort(userRecords, (r1, r2) -> Integer.compare(r2.getScore(), r1.getScore()));
        return userRecords;
    }

    // 获取排行榜
    public List<ScoreRecord> getScoreboard() {
        List<ScoreRecord> allRecords = loadScores();
        Collections.sort(allRecords, (r1, r2) -> Integer.compare(r2.getScore(), r1.getScore()));
        return allRecords.subList(0, Math.min(allRecords.size(), 10));
    }

    public GameState getCurrentGame() {
        return currentGame;
    }
}